package com.heima.wemedia.service.impl;


import com.alibaba.fastjson.JSON;
import com.hankcs.hanlp.corpus.io.ByteArrayFileStream;
import com.heima.apis.article.IArticleClient;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.aliyun.MyGreenImageScan;
import com.heima.common.constant.GlobalConstant;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.dots.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.wemedia.properties.TrainedDataProperties;
import com.heima.wemedia.service.*;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
@Slf4j
public class WmNewsAutoAuditServiceImpl implements WmNewsAutoAuditService {
    @Autowired
    WmNewsService wmNewsService;
    @Autowired
    MyGreenImageScan greenImageScan;
    @Autowired
    GreenTextScan greenTextScan;

    @Autowired
    WmSensitiveService wmSensitiveService;
    @Autowired
    TrainedDataProperties trainedDataProperties;
    @Autowired
    FileStorageService fileStorageService;

    @Autowired
    WmNewsTaskService wmNewsTaskService;
    @Async
    @Override
    public void autoAuditNews(Integer id) {
        //判断参数
        if(id==null)
        {
            throw new RuntimeException(AppHttpCodeEnum.PARAMS_NOT_NULL.getErrorMessage());
        }
        //判断文章是否存在
        WmNews news = wmNewsService.getById(id);
        if(news==null)
        {
            throw new RuntimeException(AppHttpCodeEnum.NEWS_NOT_EXIST.getErrorMessage()+"---文章id"+id);
        }
        Map<String, Object> map = parseContentAndPicture(news);
        //审核文章内容
        if(!auditNewsContent(news.getId(),(String)map.get(GlobalConstant.TEXT_TAG)))
            return;
        //审核文章图片
        if(!auditNewsImages(news.getId(),(List<String>)map.get(GlobalConstant.IMAGE_TAG)))
            return;
        //修改状态
        wmNewsService.updateStatusAndReason(news.getId(),WmNews.Status.SUCCESS,GlobalConstant.AUDIT_SUCCESS);
        //添加任务
        wmNewsTaskService.addNewsToTask(news.getId(),news.getPublishTime());
//        saveOrUpdateAppArticle(news);
    }
    public Map<String,Integer> auditSensitives(String content)
    {
        List<WmSensitive> list = wmSensitiveService.list();
        List<String> collect = list.stream().map(WmSensitive::getSensitives).collect(Collectors.toList());
        SensitiveWordUtil.initMap(collect);
        return SensitiveWordUtil.matchWords(content);
    }

    public boolean auditNewsContent(Integer id,String content){
        Map<String, Integer> stringIntegerMap = auditSensitives(content);
        if (stringIntegerMap.size()>0)
        {
            wmNewsService.updateStatusAndReason(id,WmNews.Status.FAIL,GlobalConstant.SENSITIVE_CONTENT_IN_THE_ARTICLE+stringIntegerMap);
            return false;
        }
        Map map = null;
        try{
            map = greenTextScan.greeTextScan(content);
        }catch (Exception e){
            e.printStackTrace();
        }
        if(map!=null){
            wmNewsService.updateStatusAndReason(id,WmNews.Status.FAIL,map.toString());
            return false;
        }

        return true;
    }
    public Map<String,Integer> auditImageSensitive(List<String> imgUrls)
    {
        String  imgContents="";
        for (String imgUrl : imgUrls) {
            try {
                String imgContent = tess4jORCImage(imgUrl);
                imgContents+=imgContent+"\n";
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (TesseractException e) {
                throw new RuntimeException(e);
            }

        }
        return auditSensitives(imgContents);
    }
    public boolean auditNewsImages(Integer id,List<String> imgUrls)
    {
        Set<String> set=new HashSet<>(imgUrls);
        imgUrls=set.stream().collect(Collectors.toList());
        Map<String, Integer> stringIntegerMap = auditImageSensitive(imgUrls);
        if (stringIntegerMap.size()>0)
        {
            wmNewsService.updateStatusAndReason(id,WmNews.Status.FAIL,GlobalConstant.SENSITIVE_CONTENT_IN_THE_ARTICLE+stringIntegerMap);
            return false;
        }
        Map map = null;
        try{
            map = greenImageScan.imageScan(imgUrls);
        }catch (Exception e){
            e.printStackTrace();
        }
        if(map!=null)
        {
            wmNewsService.updateStatusAndReason(id,WmNews.Status.FAIL,map.toString());
            return false;
        }
        return true;
    }


    private Map<String,Object> parseContentAndPicture(WmNews wmNews)
    {
        if(wmNews==null)
        {
            throw new RuntimeException(AppHttpCodeEnum.PARAMS_NOT_NULL.getErrorMessage());
        }
        List<Map> maps = JSON.parseArray(wmNews.getContent(), Map.class);
        String content="";
        List<String> imgUrls=new ArrayList<>();
        for (Map map : maps) {
            String key = (String)map.get(GlobalConstant.TYPE_TAG);
            String value=(String)map.get(GlobalConstant.VALUE_TAG);
            if (key.equals(GlobalConstant.TEXT_TAG))
            {
                content+=value+"\n";
            }
            else if(key.equals(GlobalConstant.VALUE_TAG))
            {
                imgUrls.add(value);
            }
        }
        if (StringUtils.isNotBlank(wmNews.getImages()))
        {
            imgUrls.addAll(Arrays.asList(wmNews.getImages().split(",")));
        }
        Map<String,Object> map=new HashMap<>();
        map.put(GlobalConstant.TEXT_TAG,content);
        map.put(GlobalConstant.IMAGE_TAG,imgUrls);
        return map;
    }

    public String tess4jORCImage(String imgUrl) throws IOException, TesseractException {
        ITesseract tesseract=new Tesseract();
        tesseract.setDatapath(trainedDataProperties.getFilePath());
        tesseract.setLanguage(GlobalConstant.CHI_SIM_TAG);
        byte[] bytes = fileStorageService.downLoadFile(imgUrl);
        ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(bytes);
        return tesseract.doOCR(ImageIO.read(byteArrayInputStream));
    }
}
